/*
 *  Plot Area Widget (where the data is plotted)
 */

#include <QtGui>
#include "plotarea.h"

PlotArea::PlotArea( vector<float> &fData, QWidget *parent ) : QFrame( parent ) {

//	setBackgroundRole(QPallete::Base);
    setAutoFillBackground(true);

    // Setup default plot items
    numYTick = 5;
    numXTick = 7;
    // Mouse Inteface with plot area
    storePosition  = 1;
    storeXPosition = 0;
    storeYPosition = 0;
    plotData = fData;

    resizeFlag = false;
    firstTime  = true;

    bgMap = new MapGrab;
    // Turn on mouse tracking
    if (!hasMouseTracking()) {
        cout << "Mouse Tracking (?):  " << hasMouseTracking() << endl;
        setMouseTracking(1);
    }
    cout << "Mouse Tracking (on):  " << hasMouseTracking() << endl;

    installEventFilter( this );

    // Parse the data into a float vector
    //readData( data, plotData);
    // Connect update signal to update command
    connect(bgMap, SIGNAL(updated(QRect)), this, SLOT(updateMap(QRect)));

}

void PlotArea::updateMap(const QRect &r) {
    // Have to call to update pix-map after receiving network data!!!
    update(r);
}

void PlotArea::readData(vector<float> &data, vector<float> &plotData) {

}

void PlotArea::readData(vector<int> &data, vector<float> &plotData) {

}

void PlotArea::paintEvent( QPaintEvent *pev ) {

    float xMax;
    float xMin;
    float yMax;
    float yMin;
    float yZero;
    float yStepSize;
    float xStepSize;
    float yGrid;
    float xGrid;

    float xVals[20];
    float yVals[20];
    float xLocs[20];
    float yLocs[20];

    float fHeight = height() - 10;
    float fWidth  = width() - 5;

    //findMaxMin( &yMax, &yMin);
    yMax = *( max_element( plotData.begin(), plotData.end() ));
    yMin = *( min_element( plotData.begin(), plotData.end() ));

    xMax = ( plotData.size() - 1 ) * 1e-3; // Update for type 1000 file
    xMin = 0;

    yZero = fHeight / (yMax - yMin); // Need to change to yStepSize
    yStepSize = (yMax - yMin) / fHeight;

    //cout << yStepSize << "," << yZero << "," << fHeight << "," << yMax << "," << yMin << endl;

    xStepSize = fWidth / (xMax - xMin);

    //cout << xStepSize << "," << fWidth << "," << xMax << "," << xMin << endl;

    QFrame::paintEvent(pev);

    QPainter painter(this);

    // Query for a map background
    if ( !resizeFlag || firstTime ) {
        bgMap->width  = this->width();
        bgMap->height = this->height();
        // Calculate zoom level
        bgMap->zoom   = bgMap->zoomCalculation( 39.7313160, 10000 / this->width() );

        bgMap->invalidate();
        bgMap->render(&painter, pev->rect(), false );
        qDebug() << "PlotArea::paintEvent:MapGrab Zoom Level - " << bgMap->zoom;

        firstTime = false;
    } else {
        bgMap->render(&painter, pev->rect(), resizeFlag );
        resizeFlag = false;
    }



    vector<QLine> lineList;
    QLine tmpLine;
    for(int dx = 0; dx < plotData.size()-1; dx++){
        tmpLine.setLine( round( xStepSize * dx * 1e-3) + 2,       round( -yZero * plotData.at(dx) + yZero )+5,
                         round( xStepSize * (dx + 1)*1e-3)+2, round( -yZero * plotData.at(dx+1) + yZero )+5);
        lineList.push_back(tmpLine);
    }


    xGrid = (xMax - xMin) / ( numXTick - 1);
    yGrid = (yMax - yMin) / ( numYTick - 1);

    //QPixmap testImage;
    //testImage.load("./data/starting_Image.png");
    //painter.drawPixmap(2,2,this->width()-10, this->height()-10, testImage);
    //QPalette pal;
    //pal.setBrush( this->backgroundRole(), QBrush( QImage( "./data/starting_Image.png")));
    //this->setPalette( pal );


    QPen pen;
    pen.setStyle(Qt::DotLine);
    pen.setColor(Qt::black);
    painter.setPen(pen);

    for(int dx = 0; dx < numYTick; dx++) {
        yVals[dx] = yMax - dx * yGrid;
        yLocs[dx] = round( -yZero * yVals[dx] + yZero) + 5;
        tmpLine.setLine( 0, yLocs[dx], width()-1, yLocs[dx]);
        painter.drawLine(tmpLine);
    }

    for(int dx = 0; dx < numXTick; dx++) {
        xVals[dx] = xMin + dx * xGrid;
        xLocs[dx] = round( xStepSize * xVals[dx] ) + 2;
        tmpLine.setLine( xLocs[dx], 0, xLocs[dx], width()-1);
        painter.drawLine(tmpLine);
    }

    emit updateLabel( numXTick, numYTick, xLocs, yLocs, xVals, yVals);

    pen.setStyle(Qt::SolidLine);
    pen.setColor(Qt::blue);
    painter.setPen(pen);
    for(int dx = 0; dx < lineList.size(); dx++)
        painter.drawLine(lineList.at(dx));
}

void PlotArea::drawGrid() {

}

void PlotArea::findMaxMin( float *max, float *min) {

    float tmpMax = -1e9;
    float tmpMin =  1e9;

    for(int dx = 0; dx < plotData.size(); dx++) {

        if( plotData.at(dx) > tmpMax ) {
            tmpMax = plotData.at(dx);
        }

        if( plotData.at(dx) < tmpMin ) {
            tmpMin = plotData.at(dx);
        }
    }

    max = &tmpMax;
    min = &tmpMin;
}

void PlotArea::plotPoints() {

}

void PlotArea::placeHolder() {

  update();
  cout << "Height:  " << height() << "\nWidth:  " << width() << endl;
}

// Need to add a slot to the MainWindow to modify statusbar
bool PlotArea::eventFilter(QObject *, QEvent *ev) {

    // Check if event is a mouseMoveEvent
    if ( ev->type() == QMouseEvent::MouseMove ) {
        QMouseEvent *mmEvent = static_cast<QMouseEvent *>(ev);
        QPoint mPoint = mmEvent->pos();
        emit mousePosition( mPoint.x(), mPoint.y(),
                            mPoint.x() - storeXPosition,
                            storeYPosition - mPoint.y() );
        // Draw the zoom box
        if( zoomBox )
            zoomBox->setGeometry(QRect(mStart, mPoint).normalized());

    } else if( ev->type() == QMouseEvent::MouseButtonRelease) {
        QMouseEvent *mmEvent = static_cast<QMouseEvent *>(ev);
        QPoint mPoint = mmEvent->pos();
        // Check if it was the left mouse button and whether it is a store click
        if( mmEvent->button() == Qt::LeftButton) {
            if( (storeXPosition == mPoint.x()) &&
                (storeYPosition == mPoint.y()) ) {
                // We are in the same position as when we clicked so no zoom box
                storeXPosition = mPoint.x();
                storeYPosition = mPoint.y();

                emit mousePosition( mPoint.x(), mPoint.y(), 0, 0);
            } else {
                //resize plot
            }
            cout << "ZoomBox ("<< storeXPosition << "," << storeYPosition << "," << mPoint.x() << "," << mPoint.y() << ")" << endl;
            zoomBox->hide();
        }
    } else if( ev->type() == QMouseEvent::MouseButtonPress) {
        QMouseEvent *mmEvent = static_cast<QMouseEvent *>(ev);
        mStart = mmEvent->pos();
        // Check if it was the left mouse button and whether it is a store click
        if( mmEvent->button() == Qt::LeftButton) {
            storeXPosition = mStart.x();
            storeYPosition = mStart.y();
            // Zoom functionality
            if( !zoomBox )
                zoomBox = new QRubberBand(QRubberBand::Rectangle, this);
            zoomBox->setGeometry(QRect(mStart, QSize()));
            zoomBox->show();
        }
    // Have to add a listener for a paint event otherwise we won't draw anything
    } else if ( ev->type() == QEvent::Paint ) {
        paintEvent( (QPaintEvent *)ev);
        cout << width() << "," << height() << endl;
    } else if ( ev->type() == QEvent::Resize ) {
        resizeFlag = true;
        qDebug() << "PlotArea::eventFilter:Resize Event Occurred";
    }

    qDebug() << "PlotArea::eventFilter:Resize Flag Value - " << resizeFlag;
    qDebug() << "PlotArea::eventFilter:Event Type - " << ev->type();

    return 1;

}
